/* Filename: shm.c
 * Description: 共享内存实现父读子写
 * Last modified: humble 20200526 20:37
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define MEMSIZE (1024)

static void usage(void);

int main(int argc, char **argv)
{
    int shmid;
    pid_t pid;
    char *ptr;

    if(argc != 1){
        fprintf(stderr, "argc !=1");
        usage();
        exit(1);
    }

    //key = ftok(); //因为俩进程有亲缘关系，故无需ftok生成key

    shmid = shmget(IPC_PRIVATE, MEMSIZE, 0600);
    if(shmid < 0){ perror("shmget()"); exit(1); }

    pid = fork();
    if(pid < 0){ perror("fork()"); exit(1); }

    if(pid == 0){ //child write
        ptr = shmat(shmid, NULL, 0);
        if(ptr == (void *)-1){ perror("shmat()"); exit(1); }

        strcpy(ptr, "hello!");

        if(shmdt(ptr) < 0){ perror("shmdt()"); exit(1); }
        exit(1);
    }
    else{ //parent read
        wait(NULL);
        ptr = shmat(shmid, NULL, 0);
        if(ptr == (void *)-1){ perror("shmat()"); exit(1); }

        puts(ptr);

        if(shmdt(ptr) < 0){ perror("shmdt()"); exit(1); }

        if(shmctl(shmid, IPC_RMID, NULL) < 0){ perror("shmctl()"); exit(1); }
        exit(0);
    }

    return 0;
}

static void usage(void)
{
#define USAGE "Usage:\n\
  Helloworld\n"
    printf(USAGE);
}
